package cn.schoolwow.quickdao.module.database.ddl.query.kit;

import cn.schoolwow.quickdao.domain.database.ddl.IndexField;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.domain.entity.common.TableColumn;
import cn.schoolwow.quickdao.module.database.ddl.query.flow.property.GetTableColumnListFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.service.entity.*;
import cn.schoolwow.quickdao.module.database.ddl.query.service.index.GetEntityIndexFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.service.index.GetSingleEntityIndexFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.service.index.HasConstraintFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.service.index.HasIndexCompositeBusiness;
import cn.schoolwow.quickdao.module.database.ddl.query.service.property.GetPropertyCompositeBusiness;
import cn.schoolwow.quickdao.module.database.ddl.query.service.property.GetPropertyListCompositeBusiness;
import cn.schoolwow.quickdao.module.database.parent.kit.DatabaseDAOImpl;
import cn.schoolwow.quickflow.QuickFlow;
import cn.schoolwow.quickflow.domain.FlowContext;

import java.util.List;

public class DatabaseDefinitionQueryImpl extends DatabaseDAOImpl implements DatabaseDefinitionQuery {
    public DatabaseDefinitionQueryImpl(QuickFlow quickFlow) {
        super(quickFlow);
    }

    @Override
    public boolean hasTable(Class clazz) {
        Entity entity = quickDAOConfig.getEntityByClassName(clazz.getName());
        return hasTable(entity.tableName);
    }

    @Override
    public boolean hasTable(String tableName) {
        FlowContext flowContext = quickFlow.startFlow(new HasTableFlow())
                .putTemporaryData("tableName", tableName)
                .execute();
        boolean hasResult = flowContext.checkData("hasResult", boolean.class);
        return hasResult;
    }

    @Override
    public boolean hasColumn(Class clazz, String columnName) {
        FlowContext flowContext = quickFlow.startFlow(new HasTableColumnFlow())
                .putTemporaryData("clazz", clazz)
                .putTemporaryData("columnName", columnName)
                .execute();
        boolean hasResult = flowContext.checkData("hasResult", boolean.class);
        return hasResult;
    }

    @Override
    public boolean hasColumn(String tableName, String columnName) {
        FlowContext flowContext = quickFlow.startFlow(new HasTableColumnFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("columnName", columnName)
                .execute();
        boolean hasResult = flowContext.checkData("hasResult", boolean.class);
        return hasResult;
    }

    @Override
    public List<String> getTableNameList(){
        FlowContext flowContext = quickFlow.executeFlow(new GetTableNameListFlow());
        List<String> tableNameList = flowContext.getData("tableNameList", List.class);
        return tableNameList;
    }

    @Override
    public List<Entity> getDatabaseEntityList() {
        FlowContext flowContext = quickFlow.executeFlow(new GetDatabaseEntityListCompositeBusiness());
        List<Entity> entityList = flowContext.getData("entityList", List.class);
        return entityList;
    }

    @Override
    public Entity getDatabaseEntity(String tableName) {
        FlowContext flowContext = quickFlow.startFlow(new GetDatabaseEntityCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .execute();
        Entity entity = flowContext.getData("entity", Entity.class);
        return entity;
    }

    @Override
    public List<Property> getPropertyList(Class clazz) {
        Entity entity = quickDAOConfig.getEntityByClassName(clazz.getName());
        return getPropertyList(entity.tableName);
    }

    @Override
    public List<Property> getPropertyList(String tableName) {
        Entity entity = new Entity();
        entity.tableName = tableName;
        FlowContext flowContext = quickFlow.startFlow(new GetPropertyListCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("entity", entity)
                .execute();
        //若从缓存中获取则必须这样写代码
        entity = flowContext.checkData("entity", Entity.class);
        return entity.properties;
    }

    @Override
    public List<TableColumn> getTableColumnList(String tableName) {
        Entity entity = new Entity();
        entity.tableName = tableName;
        FlowContext flowContext = quickFlow.startFlow(new GetPropertyListCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("entity", entity)
                .execute();
        flowContext.executeFlowList(new GetTableColumnListFlow());
        List<TableColumn> tableColumnList = flowContext.getData("tableColumnList", List.class);
        return tableColumnList;
    }

    @Override
    public Property getProperty(Class clazz, String columnName) {
        Entity entity = quickDAOConfig.getEntityByClassName(clazz.getName());
        return getProperty(entity.tableName, columnName);
    }

    @Override
    public Property getProperty(String tableName, String columnName) {
        FlowContext flowContext = quickFlow.startFlow(new GetPropertyCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("columnName", columnName)
                .execute();
        Property property = flowContext.getData("property", Property.class);
        if(null==property){
            throw new IllegalArgumentException("指定表的指定字段不存在!表名:"+tableName+",字段名:"+columnName);
        }
        return property;
    }

    @Override
    public boolean hasIndex(String tableName, String indexName) {
        FlowContext flowContext = quickFlow.startFlow(new HasIndexCompositeBusiness())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("indexName", indexName)
                .execute();
        boolean hasResult = flowContext.checkData("hasResult", boolean.class);
        return hasResult;
    }

    @Override
    public boolean hasConstraint(String tableName, String constraintName) {
        FlowContext flowContext = quickFlow.startFlow(new HasConstraintFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("constraintName", constraintName)
                .execute();
        boolean hasResult = flowContext.checkData("hasResult", boolean.class);
        return hasResult;
    }

    @Override
    public List<IndexField> getIndexFieldList(String tableName) {
        Entity entity = new Entity();
        entity.tableName = tableName;
        quickFlow.startFlow(new GetEntityIndexFlow())
                .putTemporaryData("entity", entity)
                .execute();
        for(IndexField indexField:entity.indexFieldList){
            indexField.tableName = tableName;
        }
        return entity.indexFieldList;
    }

    @Override
    public IndexField getIndexField(String tableName, String indexName) {
        FlowContext flowContext = quickFlow.startFlow(new GetSingleEntityIndexFlow())
                .putTemporaryData("tableName", tableName)
                .putTemporaryData("indexName", indexName)
                .execute();
        return flowContext.getData("indexField", IndexField.class);
    }

}